/* UniApo: DBSFileEditor
 * filename:  main.cpp
 * date:      April 2010
 * author:    Jeffrey Geyssens
 * about:     This file contains implementation of the DBS Editor.
 *            It provides the interface for DBS file modification.
 *            It can be invoked on it's own, auto-detected by UniApoFileEditor
 *            or by using the ui.
 * usage:     DBSEditor -n filename.DBS (creates a new DBS file on disk)
 *            DBSEditor -d filename.DBS (removes DBS file from disk)
 *            DBSEditor -o filename.DBS (opens a DBS file)
 *            Once a file is opened, the user is provided an interface which
 *            allows the following actions:
 *              a: add a DDL statement.
 *              m: modify a DDL statement.
 *              b: add DDL statements in bulk from any text file.
 *            As is the case in all UniApo file editors:
 *              h: displays hardcoded help content.
 *              s: builds file from objects and saves to disk.
 *              q: quit and return to OS.
 *
 * Marked as completed: 10th june 2010 and no changes since
 */
#include <iostream>
#include <string>
#include <fstream>
#include "../UniApoLib/DBSFile.h"

using namespace std;

int main(int argc, char **argv) {
    //TODO: CHECK IF NO ARGS FOR NULL ERROR
    if (argc != 3) {
        cerr << "ERROR (DBS File Editor): Requires two arguments" << endl;
        return 1;
    }
    //Get input from commandline
    void processLine(string const & lineData);
    string option = argv[1]; //expecting option of type '-x'.
    string file = argv[2]; //expecting file of type 'x.DBS'.
    string filename = file.substr(0, file.size() - 4); //omit .DBS for filename.
    string extension = file.substr(file.size() - 4, file.size()); //expects .DBS.

    //First we check if a correct filetype was supplied
    if (extension != ".DBS") {
        cerr << "ERROR (DBS File Editor): in file extension:" << endl;
        cerr << "Expected filename.DBS extension" << endl;
        return 3;
    }
    //Next we check if the option format supplied is correct
    //If the size of the argument (which must be 2) is incorrect
    //or the argument does not start with '-'
    if ((option.size() != 2) || (option.at(0) != '-')) {
        cerr << "ERROR (DBS File Editor): 1st argument incorrect: " << endl;
        cerr << "Use -n for new file,";
        cerr << " -o for open existing file or -d to delete a file." << endl;
        return 2;
    }

    //We create the DBSFile object to be used..
    DBSFile openDBS;
    //And set it's name (and subsequently it's path)
    openDBS.name(filename);

    //Check the provided argument
    char coption = option.at(1); //n,e or,d
    switch (coption) {
        case 'n':
        {
            openDBS.buildFile();
            cout << "New File Created" << endl;
            coption = 'o'; //Now open the new file,
            //ugly but does the trick
        }
        case 'o':
        {
            cout << "Open Existing File" << endl;

            //TO-DO: check if file exists and if not generate error.
            //Load Contents from file and show contents
            openDBS.loadFile();
            cout << "File opened (showing contents)" << endl;

            openDBS.print();

            string mod;
            while (mod != "q") {//while not quit
                //enter commands
                cout << "Enter command (a,m,d,b,q,s or h): ";
                getline(cin, mod);
                //Build and save file
                if (mod == "h") {
                    cout << "---DBSEditor Help---" << endl;
                    cout << "Type a to add DDL Statement" << endl;
                    cout << "Type m to modify DDL Statement" << endl;
                    cout << "Type d to delete DDL Statement" << endl;
                    cout << "Type b to DDL Statements in bulk" << endl;
                    cout << "Type s to save and q to quit" << endl;
                }
                if (mod == "s") {
                    cout << "saving" << endl;
                    openDBS.buildFile();
                    cout << "file saved" << endl;
                }
                //Add DDL Statments using vim and then bulk adding
                //Highly experimental
                if (mod == "l") {
                    //Get newpath;

                    system("cp empty new");
                    system("vim new");          
                    system("rm new");
                    
                    openDBS.print();
                }

                if (mod == "a") {
                    string SQL;
                    cout << "Add Statement" << endl;
                    cout << "Enter SQL Statement(CREATE TABLE OR INSERT): ";
                    cout << endl;
                    getline(cin, SQL);
                    openDBS.addStatement(SQL);
                    openDBS.print();
                }
                if (mod == "d") {
                    cout << "Delete Statement" << endl;
                    //TO-DO: Typecheck integer
                    int entryNo;
                    string eline;
                    cout << "Enter entry number: ";
                    getline(cin, eline);
                    if (eline != "#")
                    {
                    stringstream ss(eline);
                    ss >> entryNo;
                    cout << "Deleting: " << entryNo << endl;
                    openDBS.removeStatement(entryNo);
                    openDBS.print();
                    }
                }
                if (mod == "m") {
                    string xSQL;
                    cout << "Modify Statement" << endl;
                    cout << "Enter DDL SQL Statement: ";
                    getline(cin, xSQL);
                    int entryNo;
                    string eline;
                    cout << "Enter entry number: ";
                    getline(cin, eline);
                    stringstream ss(eline);
                    ss >> entryNo;
                    cout << entryNo;
                    cout << "Modifying:" << entryNo << endl;
                    openDBS.modifyStatement(xSQL, entryNo);
                    cout << "Modified:" << entryNo << endl;
                    openDBS.print();
                }

                if (mod == "b") {
                    string bulkpath;
                    cout << "Enter bulk file path: ";
                    getline(cin, bulkpath);
                    openDBS.bulk(bulkpath);
                }
            }
        }
            break;

        case 'd':
        {
            //TO DO: are you sure?
            if (remove(openDBS.getPath().c_str()) != 0) {
                cerr << "ERROR (DBS File Editor): No such file" << endl;
                return 4;
            } else
                cout << "File deleted" << endl;
        }
            break;

        default:
        {
            cerr << "ERROR (DBS File Editor):";
            cerr << "1st argument must be -n for new file, ";
            cerr << "-o for open existing file or -d to delete a file" << endl;
            return 2;
        }
            break;
    }
    return 0;
}
